home *** CD-ROM | disk | FTP | other *** search
-
- #include <stdio.h>
- #include <stdlib.h>
- #include "list.h"
-
-
- int list_resize();
-
- /* list.c a set of standard list routines.
-
- These routines implement a list of pointers to generic objects.
-
- the LIST pointer is a pointer to a header block for the list, which
- points to an array of pointers to the generic data type.
-
-
- */
-
- /* list_open:
- create a list pointer for subsequent operations
- */
- LIST *
- list_open(size)
- int size;
- {
- LIST *l;
-
- if ( (l = ((LIST *) malloc ((unsigned) (sizeof (LIST))))) == NULL )
- { fprintf (stderr, "list_open: no room for list\n");
- return NULL;
- }
- if (size <= 0)
- { fprintf (stderr, "list_open: bad size parameter\n");
- return NULL;
- }
- l->listdiscipline = FIFO; /* queue by default */
- if ( (l->list = (list_data_type **)malloc((unsigned) ((1+size) * (sizeof (list_data_type *))))) == NULL )
- { fprintf (stderr, "list_open: %d is too big for a list\n", size);
- return NULL;
- }
- l->listlast = &l->list[size];
- l->listhead = &l->list[0];
- l->listtail = &l->list[0];
- return (l);
- }
-
-
- /* list_close:
- remove a list and free memory
- */
- void
- list_close(ld)
- LIST *ld;
- {
- /*^ if checks added -paul */
- if (ld != NULL)
- { if (ld->list != NULL)
- { free (ld->list);
- }
- free (ld);
- }
- }
-
- /* list_empty:
- returns true if the list is empty,
- false if the list is not empty.
- */
- int
- list_empty (ld)
- LIST *ld;
- {
- if (ld == NULL)
- { fprintf (stderr, "list_empty: null list pointer\n");
- return (-1);
- } else
- { return (ld->listhead == ld->listtail);
- }
- }
-
- /* list_clear:
- resets the list to so that list_empty returns true, and the list
- can be filled to its max size.
- */
- void
- list_clear (ld)
- LIST *ld;
- {
- ld->listhead = ld->listtail;
- }
-
- /* list_next:
- returns pointer to the next element in the list
- */
- list_data_type **
- list_next(ld, p)
- LIST *ld;
- list_data_type **p;
- {
- if (p == ld->listlast)
- { return (&ld->list[0]);
- } else
- { return (p + 1);
- }
- }
-
-
- /* list_prev:
- returns pointer to previous element in the list
- */
- list_data_type **
- list_prev(ld, n)
- LIST *ld;
- list_data_type **n;
- {
- if (n == &ld->list[0])
- { return (ld->listlast);
- } else
- { return (n - 1);
- }
- }
-
-
- /* list_full:
- returns ture if the list is full
- */
- int
- list_full(ld)
- LIST *ld;
- {
- return (list_prev(ld, ld->listhead) == ld->listtail);
- }
-
-
- /* list_push:
- push an element onto the head of the list
- returns pointer to position in list
- */
- list_data_type **
- list_push(ld, p)
- LIST *ld;
- list_data_type *p;
- {
- if ( !list_full(ld))
- { *(ld->listhead) = p;
- ld->listhead = list_prev(ld, ld->listhead);
- return (list_next(ld, ld->listhead));
- } else
- { return (NULL);
- }
- }
-
-
- /* list_pop:
- pops the top element off the head of the list
- returns popped element or NULL if list is empty
- */
- list_data_type *
- list_pop(ld)
- LIST *ld;
- {
- if (!list_empty(ld))
- { ld->listhead = list_next(ld, ld->listhead);
- return (*(ld->listhead));
- } else
- { return (NULL);
- }
- }
-
- /* list_top:
- returns pointer to first element in list
- NULL if list is empty
- */
- list_data_type *
- list_top(ld)
- LIST *ld;
- {
- if (!list_empty(ld))
- { return (*list_next(ld, ld->listhead));
- } else
- { return (NULL);
- }
- }
-
- /* list_enqueue:
- puts the element passed at the back of the list
- returns pointer to the new poition in the list,
- or NULL if the list is full
- */
- list_data_type **
- list_enqueue(ld, p)
- LIST *ld;
- list_data_type *p;
- {
- if (!list_full(ld))
- { ld->listtail = list_next (ld, ld->listtail);
- *(ld->listtail) = p;
- return (ld->listtail);
- } else
- { return (NULL);
- }
- }
-
- /* list_unqueue:
- removes the element at the end of the list (as if it
- had just been added by list_enqueue). returns a
- pointer to the element removed, or NULL if list
- was empty
- */
- list_data_type *
- list_unqueue(ld)
- LIST *ld;
- {
- if (!list_empty(ld))
- { ld->listtail = list_prev (ld, ld->listtail);
- return (*list_next(ld, ld->listtail));
- } else
- { return (NULL);
- }
- }
-
- /* list_dequeue:
- removes the element from the front of the list
- and returns it or NULL if the list was empty
- */
- list_data_type *
- list_dequeue(ld)
- LIST *ld;
- {
- if (!list_empty(ld))
- { ld->listhead = list_next (ld, ld->listhead);
- return (*(ld->listhead));
- } else
- { return (NULL);
- }
- }
-
-
- /* list_discipline:
- sets the list discipline to stack or queue
- returns the old type
- */
- int
- list_discipline(ld, discipline)
- LIST *ld;
- int discipline;
- {
- int odiscipline;
-
- odiscipline = ld->listdiscipline;
- ld->listdiscipline = discipline;
- return (odiscipline);
- }
-
-
- /* list_put:
- adds an element to the list dependent on the list type
- returns a pointer to the new list element
- */
- list_data_type **
- list_put(ld, p)
- LIST *ld;
- list_data_type *p;
- {
- if (list_full (ld))
- { if (list_resize (ld, 2*list_size(ld)) < 0)
- { fprintf (stderr, "list_put: aborted\n");
- return (NULL);
- }
- }
- if (ld->listdiscipline == FIFO)
- { return (list_enqueue(ld, p));
- } else
- { return (list_push(ld, p));
- }
- }
-
- /* list_get:
- gets the next element from the list
- dependent on the queue type returns next element
- */
- list_data_type *
- list_get(ld)
- LIST *ld;
- {
- if (list_empty (ld))
- { return (NULL);
- }
- if (ld->listdiscipline == FIFO)
- { return (list_dequeue(ld));
- } else
- { return (list_pop(ld));
- }
- }
-
-
- /* list_put_nth:
- replaces the nth element of the list with the passed element
- */
- list_data_type **
- list_put_nth (ld, n, element)
- LIST *ld;
- int n;
- list_data_type *element;
- {
- list_data_type **spot;
- int off;
-
- if (n >= list_size(ld))
- { return (NULL);
- }
- spot = 1 + ld->listhead + n;
- off = spot - ld->listlast;
- if (off <= 0)
- { *spot = element;
- return (spot);
- } else
- { *(ld->list + off) = element;
- return (ld->list + off);
- }
- }
-
-
- /* list_copy:
- makes a copy of the from list and puts it into the to list
- */
- int
- list_copy(ldto, ldfrom)
- LIST *ldto, *ldfrom;
- {
- int size, count;
- list_data_type *fromfinger;
-
- size = list_size (ldfrom);
- if (size > ldto->listlast - ldto->list)
- { fprintf (stderr, "list_copy: source list too big for destination\n");
- return (-1);
- }
- list_clear (ldto);
- for (count = 0; count < size; count++)
- { fromfinger = list_get_nth (ldfrom, count);
- list_put (ldto, fromfinger);
- }
- return (1);
- }
-
- /* list_resize:
- changes the size of the list, e.g. makes it larger so that
- a list which was full (true from list_full) will now not
- be full
- */
- int
- list_resize (ld, size)
- LIST *ld;
- int size; /* new size of list array */
- {
- LIST *newlist, *temp;
-
- if (list_size(ld) >= size)
- { fprintf (stderr, "list_resize: new size too small\n");
- return (int)NULL;
- }
- /* make new list as copy of old, only larger */
- newlist = list_open (size);
- if (list_copy (newlist, ld) < 0)
- { list_close (newlist);
- fprintf (stderr, "list_resize: aborted\n");
- return (-1);
- }
- newlist->listdiscipline = ld->listdiscipline;
-
- /* move new list into old location */
- temp = (LIST *) malloc ((unsigned) (sizeof (LIST)));
- *temp = *ld; /* save old LIST header */
- *ld = *newlist; /* make the passed pointer point to the new header */
- list_close (temp); /* get rid of the original list */
- free (newlist); /* get rid of extra header */
- return (1);
- }
-
- /* list_delete_nth:
- removes the nth element from the list and closes in the remaining
- elements of the list
- */
- list_data_type *
- list_delete_nth(ld, n)
- LIST *ld;
- int n;
- {
- int size,count;
- list_data_type *tmp, *return_el;
-
- size = list_size(ld);
- if (n >= size)
- { fprintf(stderr, "list_delete_nth: n is greater than list size\n");
- return(NULL);
- }
- return_el = list_get_nth (ld, n);
- for (count = n; count < size-1; count++)
- { tmp = (list_data_type *) list_get_nth(ld, count+1);
- list_put_nth(ld, count, tmp);
- }
- list_unqueue(ld);
- return (return_el);
- } /* list_delete_nth */
-
-
- /* list_delete_element:
- removes the element from the list and closes in the remaining
- elements of the list
- */
- list_data_type *
- list_delete_element(ld, element)
- LIST *ld;
- list_data_type *element;
- {
- int size,count;
- list_data_type *tmp;
-
- if (ld == NULL)
- { fprintf (stderr, "list_delete_element: bad list\n");
- return (NULL);
- }
- size = list_size(ld);
- for (count = 0; count < size; count++)
- { tmp = (list_data_type *) list_get_nth(ld, count);
- if (tmp == element)
- { list_delete_nth(ld, count);
- return (element);
- }
- }
- return (NULL);
- } /* list_delete_element */
-
-
- /* list_insert_nth:
- puts the passed element into the nth location in the passed list,
- and moves the old elements back to make room. the list becomes
- one larger. returns the pointer to the new location, or NULL if
- there was an error. list_insert_nth will double the size of the
- list if there was no room for the inserted element.
- */
- list_data_type **
- list_insert_nth (ld, n, p)
- LIST *ld;
- int n;
- list_data_type *p;
- {
- int size, count;
- list_data_type *t;
-
- if (n < 0 || n >= list_size(ld))
- { fprintf (stderr, "list_insert_nth: bad instert location %d\n",n);
- return (NULL);
- }
- if (list_full (ld))
- { if (list_resize (ld, 2*list_size(ld)) < 0)
- { fprintf (stderr, "list_insert_nth: aborted\n");
- return (NULL);
- }
- }
- list_enqueue (ld, p); /* add a new spot at the end of the list */
- size = list_size (ld);
- /* slide all behind nth back */
- for (count = size - 1; count >=n; count--)
- { t = list_get_nth (ld, count-1);
- list_put_nth (ld, count, t);
- }
- return (list_put_nth (ld, n, p)); /* p becomes nth */
- }
-
-
- int
- list_element_get_index (ld, el)
- LIST *ld;
- list_data_type *el;
- {
- int size, count;
-
- size = list_size (ld);
- for (count = 0; count < size; count++)
- { if (el == list_get_nth (ld, count))
- { return (count);
- }
- }
- return (-1);
- }
-
- /* nb: list_size and list_get_nth have been replaced by macro
- versions in list.h. These are kept around for any files that have
- not been recompiled with the new list.h */
-
- #undef list_size
- /* list_size:
- returns the number of elements in the list
- */
- int
- list_size (ld)
- LIST *ld;
- {
- int size;
-
- if (ld == NULL)
- { return (0);
- }
- if (ld->listhead > ld->listtail)
- { size = ld->listlast - ld->listhead;
- size += ld->listtail - ld->list + 1;
- return (size);
- } else
- { size = ld->listtail - ld->listhead;
- return (size);
- }
- }
-
- #undef list_get_nth
- /* list_get_nth:
- returns the nth element in the list (doesn't delete it)
- */
- list_data_type *
- list_get_nth (ld, n)
- LIST *ld;
- int n;
- {
- list_data_type **spot;
- int off;
-
- if (n >= list_size(ld))
- { return (NULL);
- }
- spot = 1 + ld->listhead + n;
- off = spot - ld->listlast;
- if (off <= 0)
- { return (*spot);
- } else
- { return (*(ld->list + off - 1));
- }
- }
-
-